package org.mili.ticketeer.dao;

import org.mili.application.dao.AbstractDao;
import org.mili.application.dao.DaoException;
import org.mili.application.dao.MofificationType;
import org.mili.application.dao.RowTransformer;
import org.mili.application.util.Lambda;
import org.mili.application.util.Log;
import org.mili.ticketeer.dto.Contact;
import org.mili.ticketeer.dto.ContactMeeting;
import org.mili.ticketeer.dto.Meeting;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

public class ContactMeetingDao extends AbstractDao {

    public ContactMeetingDao() {
        super(ContactMeeting.Fields.values(), ContactMeeting.Fields.values(), ContactMeeting.TABLE);
    }

    public Boolean assign(final Contact contact, final Meeting meeting) throws DaoException {
        return doInDao(new Lambda<Boolean>() {
            @Override
            public Boolean exec(Object... params) throws SQLException, DaoException {
                ContactMeeting contactMeeting = new ContactMeeting();
                contactMeeting.setContact(contact.getId());
                contactMeeting.setMeeting(meeting.getId());
                boolean result = update("insert into `contact_meeting` (`contact`, `meeting`) values(?, ?);", contact.getId(),
                        meeting.getId()) == 1;
                boolean archive = archive(contactMeeting, MofificationType.CREATE) == 1;
                return result && archive;
            }
        });
    }

    public Boolean unassign(final Contact contact, final Meeting meeting) throws DaoException {
        return doInDao(new Lambda<Boolean>() {
            @Override
            public Boolean exec(Object... params) throws SQLException, DaoException {
                ContactMeeting contactMeeting = new ContactMeeting();
                contactMeeting.setContact(contact.getId());
                contactMeeting.setMeeting(meeting.getId());
                boolean result = update("delete from `contact_meeting` where `contact`=? and `meeting`=?;", contact.getId(),
                        meeting.getId()) == 1;
                boolean archive = archive(contactMeeting, MofificationType.DELETE) == 1;
                return result && archive;
            }
        });
    }

    public List<ContactMeeting> getMeetingsFor(final Contact contact) throws DaoException {
        return doInDao(new Lambda<List<ContactMeeting>>() {
            @Override
            public List<ContactMeeting> exec(Object... params) throws SQLException {
                return query(new RowTransformer<ContactMeeting>() {
                    @Override
                    public ContactMeeting transform(ResultSet resultSet) throws SQLException {
                        ContactMeeting contactMeeting = new ContactMeeting();
                        contactMeeting.setContact(resultSet.getInt("contactid"));
                        contactMeeting.setMeeting(resultSet.getInt("meetingid"));
                        Log.log(this, "getContactMeetingsFor", "contact=%s, %s", contact.getId(), contactMeeting);
                        return contactMeeting;
                    }
                }, "select meeting.id as meetingid, (select contact_meeting.contact from contact_meeting where contact_meeting.meeting=meetingid and contact_meeting.contact=?) as contactid from meeting order by meeting.date desc", contact.getId());
            }
        });
    }

    public List<ContactMeeting> getVisitorsForMeetings(final Meeting meeting) throws DaoException {
        return doInDao(new Lambda<List<ContactMeeting>>() {
            @Override
            public List<ContactMeeting> exec(Object... params) throws SQLException {
                return query(new RowTransformer<ContactMeeting>() {
                    @Override
                    public ContactMeeting transform(ResultSet resultSet) throws SQLException {
                        ContactMeeting contactMeeting = new ContactMeeting();
                        contactMeeting.setContact(resultSet.getInt("contact"));
                        contactMeeting.setMeeting(meeting.getId());
                        Log.log(this, "getVisitorsForMeetings", "meeting=%s, %s", meeting.getId(), contactMeeting);
                        return contactMeeting;
                    }
                }, "select contact from contact_meeting where meeting=?", meeting.getId());
            }
        });
    }
}
